#include "UnitTest.h"
#include "Array.h"
#include "Object.h"
#include <string>
#include "Log.h"

namespace tinyjson
{
    size_t UnitTest::m_total_test_count = 0;
    size_t UnitTest::m_pass_test_count = 0;

    UnitTest &UnitTest::instance()
    {
        static UnitTest instance;
        return instance;
    }

    template <typename ElementType>
    bool UnitTest::expect_eq_actual(const ElementType &expect, const ElementType &actual)
    {
        m_total_test_count++;
        if (expect == actual)
        {
            m_pass_test_count++;
            return true;
        }
        else
        {
            std::cout << "In file : " << __FILE__ << " In line : " << __LINE__;
            std::cout << " Expect : " << expect << " Actual : " << actual << std::endl;
            return false;
        }
    }

    template <>
    bool UnitTest::expect_eq_actual(const TinyJsonParseRet &expect, const TinyJsonParseRet &actual)
    {
        m_total_test_count++;
        if (expect == actual)
        {
            m_pass_test_count++;
            return true;
        }
        else
        {
            std::cout << "In file : " << __FILE__ << " In line : " << __LINE__;
            std::cout << " Expect : " << static_cast<int>(expect) << " Actual : " << static_cast<int>(actual) << std::endl;
            return false;
        }
    }

    template <>
    bool UnitTest::expect_eq_actual(const TinyJsonType &expect, const TinyJsonType &actual)
    {
        m_total_test_count++;
        if (expect == actual)
        {
            m_pass_test_count++;
            return true;
        }
        else
        {
            std::cout << "In file : " << __FILE__ << " In line : " << __LINE__;
            std::cout << " Expect : " << static_cast<int>(expect) << " Actual : " << static_cast<int>(actual) << std::endl;
            return false;
        }
    }

    template <>
    bool UnitTest::expect_eq_actual(const std::string &expect, const std::string &actual)
    {
        m_total_test_count++;
        // if (strcmp(expect, actual) == 0)
        if (expect == actual)
        {
            m_pass_test_count++;
            return true;
        }
        else
        {
            std::cout << "In file : " << __FILE__ << " In line : " << __LINE__;
            std::cout << " Expect : " << expect << " Actual : " << actual << std::endl;
            return false;
        }
    }

    void UnitTest::test_all()
    {
        test_parse_all();
        test_generate_all();
        SPDLOG_LOGGER_INFO(spdlog::get("spdlog"), "Test Parser and Generater: {}/{} ({:03.2f}%) passed",m_pass_test_count,m_total_test_count,m_pass_test_count * 100.0 / m_total_test_count);
    }

    // json解析器的测试用例
    void UnitTest::test_parse_all()
    {
        test_parse_literal();
        test_parse_number();
        test_parse_string();
        test_parse_array();
        test_parse_object();
        test_parse_invalid();
    }
    void UnitTest::test_parse_literal()
    {
        test_parse_literal_case("  null ");
        test_parse_literal_case("null");
        test_parse_literal_case("\n null");
        test_parse_literal_case("  false   ");
        test_parse_literal_case("false");
        test_parse_literal_case("\n false");
        test_parse_literal_case("  true  ");
        test_parse_literal_case("true");
        test_parse_literal_case("\n true");
    }

    void UnitTest::test_parse_literal_case(const char *json)
    {
        bool bTestPass = true;
        TinyJsonReader reader;
        reader.load_from_string(json);
        reader.parse();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonParseRet::TINY_JSON_PARSE_SECCESS, reader.parse_state());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonParseRet, testing case: {}",json);
        }
        TinyJsonValue value = reader.parse_result();
        if (value.is_null())
        {
            bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_NULL, value.get_type());
        }
        else if (value.is_true())
        {
            bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_TRUE, value.get_type());
        }
        else if (value.is_false())
        {
            bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_FALSE, value.get_type());
        }
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonType, testing case: {}",json);
        }
    }

    void UnitTest::test_parse_number()
    {
        test_parse_number_case(0.0, "0");

        test_parse_number_case(0.0, "-0");

        test_parse_number_case(0.0, "-0.0");

        test_parse_number_case(1.0, "1");

        test_parse_number_case(-1.0, "-1");

        test_parse_number_case(1.5, "1.5");

        test_parse_number_case(-1.5, "-1.5");

        test_parse_number_case(3.1416, "3.1416");

        test_parse_number_case(1E10, "1E10");

        test_parse_number_case(1e10, "1e10");

        test_parse_number_case(1E+10, "1E+10");

        test_parse_number_case(1E-10, "1E-10");

        test_parse_number_case(-1E10, "-1E10");

        test_parse_number_case(-1e10, "-1e10");

        test_parse_number_case(-1E+10, "-1E+10");

        test_parse_number_case(-1E-10, "-1E-10");

        test_parse_number_case(1.234E+10, "1.234E+10");

        test_parse_number_case(1.234E-10, "1.234E-10");

        test_parse_number_case(1.0000000000000002, "1.0000000000000002");

        test_parse_number_case(4.9406564584124654e-324, "4.9406564584124654e-324");

        test_parse_number_case(-4.9406564584124654e-324, "-4.9406564584124654e-324");

        test_parse_number_case(2.2250738585072009e-308, "2.2250738585072009e-308");

        test_parse_number_case(-2.2250738585072009e-308, "-2.2250738585072009e-308");

        test_parse_number_case(2.2250738585072014e-308, "2.2250738585072014e-308");

        test_parse_number_case(-2.2250738585072014e-308, "-2.2250738585072014e-308");

        test_parse_number_case(1.7976931348623157e+308, "1.7976931348623157e+308");

        test_parse_number_case(-1.7976931348623157e+308, "-1.7976931348623157e+308");
    }

    void UnitTest::test_parse_number_case(Number expect, const char *json)
    {
        bool bTestPass = true;
        TinyJsonReader reader;
        reader.load_from_string(json);
        reader.parse();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonParseRet::TINY_JSON_PARSE_SECCESS, reader.parse_state());
        if (!bTestPass)
        {
            std::cout << "Error TinyJsonParseRet, testing case: " << json << std::endl;
        }
        TinyJsonValue value = reader.parse_result();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_NUMBER, value.get_type());
        if (!bTestPass)
        {
            std::cout << "Error TinyJsonType, testing case: " << json << std::endl;
        }
        Number number = value.get_number();
        bTestPass = bTestPass && expect_eq_actual(expect, number);
        if (!bTestPass)
        {
            std::cout << "Error value, testing case: " << json << std::endl;
        }
    }

    void UnitTest::test_parse_string()
    {
        test_parse_string_case("中国", "\"中国\"");

        test_parse_string_case("", "\"\"");

        test_parse_string_case("Hello", "\"Hello\"");

        test_parse_string_case("Hello\nWorld", "\"Hello\\nWorld\"");

        test_parse_string_case("\" \\ / \b \f \n \r \t", "\"\\\" \\\\ \\/ \\b \\f \\n \\r \\t\"");

        //由于std::string 只会保存到第一个\0字符。所以这个用例无法测试
        // test_parse_string_case(String("Hello\0World"), "\"Hello\\u0000World\"");

        // unicode码
        test_parse_string_case("\x24", "\"\\u0024\"");
        test_parse_string_case("\xC2\xA2", "\"\\u00A2\"");
        test_parse_string_case("\xE2\x82\xAC", "\"\\u20AC\"");
        test_parse_string_case("\xF0\x9D\x84\x9E", "\"\\uD834\\uDD1E\"");
        test_parse_string_case("\xF0\x9D\x84\x9E", "\"\\ud834\\udd1e\"");

        // printf("*********%s\n", "\x24");     // 16进制
        // printf("*********%s\n", "\xC2\xA2");
        // printf("*********%s\n", "\xE2\x82\xAC");
        // printf("*********%s\n", "\xF0\x9D\x84\x9E");
        // printf("*********%s\n", "\xF0\x9D\x84\x9E");
    }

    void UnitTest::test_parse_string_case(const String &expect, const char *json)
    {
        bool bTestPass = true;
        TinyJsonReader reader;
        reader.load_from_string(json);
        reader.parse();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonParseRet::TINY_JSON_PARSE_SECCESS, reader.parse_state());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonParseRet, testing case: {}",json);
        }
        TinyJsonValue value = reader.parse_result();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_STRING, value.get_type());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonType, testing case: {}",json);
        }
        String str = value.get_string();
        bTestPass = bTestPass && expect_eq_actual(expect, str);
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error value, testing case: {}",json);
        }
    }

    void UnitTest::test_parse_array()
    {
        test_parse_array_case("[]");

        test_parse_array_case("[123, 456, 78, [123,4,\"xxxx\", null], \"ok\"]");

        test_parse_array_case("[123,[1, 2, 3, [4, 5, 6]]]");
    }

    void UnitTest::test_parse_array_case(const char *json)
    {
        bool bTestPass = true;
        TinyJsonReader reader;
        reader.load_from_string(json);
        reader.parse();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonParseRet::TINY_JSON_PARSE_SECCESS, reader.parse_state());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonParseRet, testing case: {}",json);
        }
        TinyJsonValue value = reader.parse_result();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_ARRAY, value.get_type());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonType, testing case: {}",json);
        }
        // Array& vec = value.GetArray();
        // std::cout << vec << std::endl;
        // for(size_t i=0;i<vec.size();++i)
        // {
        //     std::cout <<"vec["<<i<<"]: "<< *vec[i] << std::endl;
        // }
    }

    void UnitTest::test_parse_object()
    {
        test_parse_object_case("{}");

        test_parse_object_case("{ \"a\" : \"1234\", \"ooo\" : { \"aa\" : 123, \"bbb\" : null, \"ccc\" : {} } }");

        const char *testcase =
            " { "

            "\"n\" : null , "

            "\"f\" : false , "

            "\"t\" : true , "

            "\"i\" : 123 , "

            "\"s\" : \"abc\", "

            "\"a\" : [ 1, 2, 3 ],"

            "\"o\" : { \"1\" : 1, \"2\" : 2, \"3\" : 3 }"

            " } ";

        TinyJsonReader reader;
        reader.load_from_string(testcase);
        reader.parse();
        expect_eq_actual(TinyJsonParseRet::TINY_JSON_PARSE_SECCESS, reader.parse_state());
        TinyJsonValue value = reader.parse_result();
        // std::cout<<value<<std::endl;
        expect_eq_actual(TinyJsonType::TINY_JSON_OBJECT, value.get_type());

        Object &obj = value.get_object();

        expect_eq_actual(TinyJsonType::TINY_JSON_NULL, obj["n"]->get_type());
        expect_eq_actual(String("null"), obj["n"]->get_null());

        expect_eq_actual(TinyJsonType::TINY_JSON_FALSE, obj["f"]->get_type());
        expect_eq_actual(String("false"), obj["f"]->get_false());

        expect_eq_actual(TinyJsonType::TINY_JSON_TRUE, obj["t"]->get_type());
        expect_eq_actual(String("true"), obj["t"]->get_true());

        expect_eq_actual(TinyJsonType::TINY_JSON_NUMBER, obj["i"]->get_type());
        expect_eq_actual(123.0, obj["i"]->get_number());

        expect_eq_actual(TinyJsonType::TINY_JSON_STRING, obj["s"]->get_type());
        expect_eq_actual(String("abc"), obj["s"]->get_string());

        expect_eq_actual(TinyJsonType::TINY_JSON_ARRAY, obj["a"]->get_type());
        Array &vec = obj["a"]->get_array();
        for (size_t i = 0; i < 3; ++i)
        {
            TinyJsonValuePtr &p = vec[i];
            expect_eq_actual(static_cast<double>(i + 1), p->get_number());
        }

        expect_eq_actual(TinyJsonType::TINY_JSON_OBJECT, obj["o"]->get_type());
        Object &o = obj["o"]->get_object();
        size_t count = 1;
        for (auto it = o.begin(); it != o.end(); it++)
        {
            auto &key = it->first;
            auto &val = it->second;
            expect_eq_actual(std::to_string(count), key);
            expect_eq_actual(static_cast<double>(count), val->get_number());
            count++;
        }
    }

    void UnitTest::test_parse_object_case(const char *json)
    {
        bool bTestPass = true;
        TinyJsonReader reader;
        reader.load_from_string(json);
        reader.parse();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonParseRet::TINY_JSON_PARSE_SECCESS, reader.parse_state());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonParseRet, testing case: {}",json);
        }
        TinyJsonValue value = reader.parse_result();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_OBJECT, value.get_type());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonType, testing case: {}",json);
        }
        // Object& obj = value.GetObject();
        // std::cout << obj << std::endl;
    }

    void UnitTest::test_parse_invalid()
    {
        /************************************************************************/
        /* 非法的字面值(null、false、true)                                                       */
        /************************************************************************/
        test_parse_invalid_case("nul");
        test_parse_invalid_case("nu");
        test_parse_invalid_case("null x");
        test_parse_invalid_case("fals");
        test_parse_invalid_case("fal se");
        test_parse_invalid_case("  trxe ");
        test_parse_invalid_case("tru");
        test_parse_invalid_case("hello");
        test_parse_invalid_case("?");
        test_parse_invalid_case("");
        test_parse_invalid_case(" ");

        /************************************************************************/
        /* 非法的数字类型                                                        */
        /************************************************************************/
        test_parse_invalid_case("0.1 * 20");
        test_parse_invalid_case("+1 + -2");
        test_parse_invalid_case(".123xx");
        test_parse_invalid_case("1.xx");
        test_parse_invalid_case("inf");

        test_parse_invalid_case("+0"); // json数字中无+号
        test_parse_invalid_case("+1");
        test_parse_invalid_case(".123"); // 缺少整数部分
        test_parse_invalid_case("1.");   // 小数点后至少有一个数
        test_parse_invalid_case("INF");  // json不认inf，nan
        test_parse_invalid_case("inf");
        test_parse_invalid_case("NAN");
        test_parse_invalid_case("nan");

        // 0是完整的number了，后面不应该还有字符
        test_parse_invalid_case("0123");

        // json数字不认0x（16进制）
        test_parse_invalid_case("0x0");
        test_parse_invalid_case("0x123");

        //字符串中包含祖母
        test_parse_invalid_case("-123a");
        test_parse_invalid_case("a-123a");
        test_parse_invalid_case("  a-123a ");
        test_parse_invalid_case("123bca-123abc ");
        //数值过大或过小
        test_parse_invalid_case("1e309");
        test_parse_invalid_case("-1e309");

        /************************************************************************/
        /* 非法的字符串类型                                                        */
        /************************************************************************/
        //缺少双引号
        test_parse_invalid_case("\"");
        test_parse_invalid_case("\"abc");
        //错误的转义字符
        test_parse_invalid_case("\"\\v\"");
        test_parse_invalid_case("\"\\'\"");
        test_parse_invalid_case("\"\\0\"");
        test_parse_invalid_case("\"\\x12\"");
        //存在小于0x20的字符
        test_parse_invalid_case("\"\x01\"");
        test_parse_invalid_case("\"\x1F\"");

        //错误的unicode
        test_parse_invalid_case("\"\\u\"");
        test_parse_invalid_case("\"\\u0\"");
        test_parse_invalid_case("\"\\u01\"");
        test_parse_invalid_case("\"\\u012\"");
        test_parse_invalid_case("\"\\u/000\"");
        test_parse_invalid_case("\"\\uG000\"");
        test_parse_invalid_case("\"\\u0/00\"");
        test_parse_invalid_case("\"\\u0G00\"");
        test_parse_invalid_case("\"\\u00/0\"");
        test_parse_invalid_case("\"\\u00G0\"");
        test_parse_invalid_case("\"\\u000/\"");
        test_parse_invalid_case("\"\\u000G\"");
        test_parse_invalid_case("\"\\u 123\"");

        test_parse_invalid_case("\"\\uD800\"");
        test_parse_invalid_case("\"\\uDBFF\"");
        test_parse_invalid_case("\"\\uD800\\\\\"");
        test_parse_invalid_case("\"\\uD800\\uDBFF\"");
        test_parse_invalid_case("\"\\uD800\\uE000\"");

        /************************************************************************/
        /* 非法的数组                                                       */
        /************************************************************************/
        test_parse_invalid_case("[1");
        test_parse_invalid_case("[1}");
        test_parse_invalid_case("[1 2");
        test_parse_invalid_case("[[]");
        test_parse_invalid_case("[1,]");
        test_parse_invalid_case("[\"a\", nul]");
        test_parse_invalid_case("[\"a\" : nul]");

        /************************************************************************/
        /* 非法的对象                                                      */
        /************************************************************************/
        test_parse_invalid_case("{:1,");
        test_parse_invalid_case("{1:1,");
        test_parse_invalid_case("{true:1,");
        test_parse_invalid_case("{false:1,");
        test_parse_invalid_case("{null:1,");
        test_parse_invalid_case("{[]:1,");
        test_parse_invalid_case("{{}:1,");
        test_parse_invalid_case("{\"a\":1,");
        test_parse_invalid_case("{\"a\"}");
        test_parse_invalid_case("{\"a\",\"b\"}");
        test_parse_invalid_case("{\"a\":1");
        test_parse_invalid_case("{\"a\":1]");
        test_parse_invalid_case("{\"a\":1 \"b\"");
        test_parse_invalid_case("{\"a\":{}");
    }

    void UnitTest::test_parse_invalid_case(const char *json)
    {
        bool bTestPass = true;
        TinyJsonReader reader;
        reader.load_from_string(json);
        reader.parse();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonParseRet::TINY_JSON_PARSE_FAIL, reader.parse_state());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonParseRet, testing case: {}",json);
        }
        TinyJsonValue value = reader.parse_result();
        bTestPass = bTestPass && expect_eq_actual(TinyJsonType::TINY_JSON_EMPTY, value.get_type());
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error TinyJsonType, testing case: {}",json);
        }
    }

    void UnitTest::test_generate_all()
    {
        //测试字面值
        test_generate_case("null");
        test_generate_case("true");
        test_generate_case("false");
        //测试数字
        test_generate_case("0");
        test_generate_case("1");
        test_generate_case("-1");
        test_generate_case("1.5");
        test_generate_case("-1.5");
        test_generate_case("3.25");
        test_generate_case("1e+20");
        test_generate_case("1.234e+20");
        test_generate_case("1.234e-20");
        test_generate_case("1.0000000000000002");      /* the smallest number > 1 */
        test_generate_case("4.9406564584124654e-324"); /* minimum denormal */
        test_generate_case("-4.9406564584124654e-324");
        test_generate_case("2.2250738585072009e-308"); /* Max subnormal double */
        test_generate_case("-2.2250738585072009e-308");
        test_generate_case("2.2250738585072014e-308"); /* Min normal positive double */
        test_generate_case("-2.2250738585072014e-308");
        test_generate_case("1.7976931348623157e+308"); /* Max double */
        test_generate_case("-1.7976931348623157e+308");
        //测试字符串
        test_generate_case("\"\"");
        test_generate_case("\"Hello\"");
        test_generate_case("\"Hello\\nWorld\"");
        test_generate_case("\"\\\" \\\\ / \\b \\f \\n \\r \\t\"");
        //测试数组
        test_generate_case("[]");
        test_generate_case("[null,false,true,123,\"abc\",[1,2,3]]");
        //测试对象
        test_generate_case("{}");
        test_generate_case("{\"a\":[1,2,3],\"f\":false,\"i\":123,\"n\":null,\"o\":{\"1\":1,\"2\":2,\"3\":3},\"s\":\"abc\",\"t\":true}");

        test_generate_tinyjsonvalue_by_hand();
    }
    void UnitTest::test_generate_case(const char *json)
    {
        TinyJsonReader reader;
        reader.load_from_string(json);
        reader.parse();
        TinyJsonValue value = reader.parse_result();

        TinyJsonWriter writer;
        writer.push(value);
        writer.stringify();
        std::string str_json2 = writer.stringify_result();
        
        bool bTestPass = true;
        
        std::string str_json(json);
        //std::string str_json2(json2);
        
        bTestPass = bTestPass && expect_eq_actual(str_json,str_json2);
        if (!bTestPass)
        {
            SPDLOG_LOGGER_ERROR(spdlog::get("spdlog"),"Error Stringify, testing case (json: {}, json2: {})",str_json,str_json2);
        }
    }

    void UnitTest::test_generate_tinyjsonvalue_by_hand()
    {
        /**********************************************
        {
        "sites": [
            { "name":"菜鸟教程" , "url":"www.runoob.com" },
            { "name":"google" , "url":"www.google.com" },
            { "name":"微博" , "url":"www.weibo.com" }
            ]
        }
        **********************************************/
        Object T1_obj1;
        T1_obj1.insert("name", "菜鸟教程");
        T1_obj1.insert("url", "www.runoob.com");
        Object T1_obj2;
        T1_obj2.insert("name", "google");
        T1_obj2.insert("url", "www.google.com");
        Object T1_obj3;
        T1_obj3.insert("name", "微博");
        T1_obj3.insert("url", "www.weibo.com");
        Array T1_arr1;
        T1_arr1.push_back(T1_obj1);
        T1_arr1.push_back(T1_obj2);
        T1_arr1.push_back(T1_obj3);
        Object T1_obj4;
        T1_obj4.insert("sites", T1_arr1);

        TinyJsonWriter T1_writer;
        T1_writer.push(T1_obj4);
        // T1_writer.Write("json/output2.txt");

        /**************************************
        {
        "title": "Design Patterns",
        "subtitle": "Elements of Reusable Object-Oriented Software",
        "author": [
            "Erich Gamma",
            "Richard Helm",
            "Ralph Johnson",
            "John Vlissides"
        ],
        "year": 2009,
        "weight": 1.8,
        "hardcover": true,
        "publisher": {
            "Company": "Pearson Education",
            "Country": "India"
        },
        "website": null
    }
        ***************************************/
        Object T2_obj1;
        T2_obj1.insert("title", "Design Patterns");
        T2_obj1.insert("subtitle", "Elements of Reusable Object-Oriented Software");
        Array T2_array1;
        T2_array1.push_back("Erich Gamma");
        T2_array1.push_back("Richard Helm");
        T2_array1.push_back("Ralph Johnson");
        T2_array1.push_back("John Vlissides");
        T2_obj1.insert("author", T2_array1);
        T2_obj1.insert("year", 2009);
        T2_obj1.insert("weight", 1.8);
        T2_obj1.insert("hardcover", "true");
        Object T2_obj2;
        T2_obj2.insert("Company", "Pearson Education");
        T2_obj2.insert("Country", "India");
        T2_obj1.insert("publisher", T2_obj2);
        T2_obj1.insert("website", "null");

        TinyJsonWriter T2_writer;
        T2_writer.push(T2_obj1);
        // T2_writer.Write("json/output2.txt");
    }
}